﻿using ArtMath.Animation;
using ArtMath.Command;
using ArtMath.Component;
using ArtMath.Control;
using ArtMath.Core.Helper;
using ArtMath.Flag;
using ArtMath.Interaction.Interface;
using ArtMath.CommonType;
using ArtMath.Parameter;
using ArtMath.Resource;
using ArtMath.Setting;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace ArtMath.Window
{
    public partial class RecycleBinWindow : Form, IRecycleDelete
    {
        [Browsable(false)]
        public SketchPad LinkedPad { get; private set; }
        [Browsable(false)]
        public Document LinkedDocument { get; private set; }
        public void Document_Activated(Document sender)
        {
            lvWastedObjects.Items.Clear();
            LinkedDocument = sender;
            if (LinkedDocument == null)
            {
                //lvWastedObjects.Enabled = toolStrip1.Enabled = false;
                Enabled = false;
            }
            else
            {
                foreach (BasicParameter item in LinkedDocument.Parameters)
                {
                    if (item.ObjectState == ObjectState.Deleted)
                    {
                        CalculatedParameter cp = item as CalculatedParameter;
                        if (cp == null || Settings.Instance.ShowOtherPadRecycleItems)
                        {
                            lvWastedObjects.Items.Add(item.RecycleItem);
                        }
                    }
                }
                if (Settings.Instance.ShowOtherPadRecycleItems)
                {
                    foreach (SketchPad pad in LinkedDocument.Pads)
                    {
                        if (pad.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(pad.RecycleItem);
                        }
                        foreach (LayerItem item in pad.Layer.Items)
                        {
                            if (item.LinkedObj == null) continue;
                            if (item.LinkedObj.ObjectState == ObjectState.Deleted)
                            {
                                lvWastedObjects.Items.Add(item.LinkedObj.RecycleItem);
                            }
                        }
                        foreach (AnimationBase ani in pad.Animations)
                        {
                            if (ani.ObjectState == ObjectState.Deleted)
                            {
                                lvWastedObjects.Items.Add(ani.RecycleItem);
                            }
                        }
                    }
                }
                //lvWastedObjects.Enabled = toolStrip1.Enabled = true;
                Enabled = true;
            }
        }
        public void SketchPad_Activated(SketchPad sender)
        {
            if (Settings.Instance.ShowOtherPadRecycleItems)
            {
                LinkedPad = sender;
            }
            else
            {
                if (LinkedPad != null)
                {
                    if (LinkedPad.ObjectState == ObjectState.Deleted)
                    {
                        LinkedPad.RecycleItem.Remove();
                    }
                    foreach (CalculatedParameter item in LinkedPad.Parameters)
                    {
                        if (item.ObjectState == ObjectState.Deleted)
                        {
                            item.RecycleItem.Remove();
                        }
                    }
                    foreach (LayerItem item in LinkedPad.Layer.Items)
                    {
                        if (item.LinkedObj == null) continue;
                        if (item.LinkedObj.ObjectState == ObjectState.Deleted)
                        {
                            item.LinkedObj.RecycleItem.Remove();
                        }
                    }
                    foreach (AnimationBase ani in LinkedPad.Animations)
                    {
                        if (ani.ObjectState == ObjectState.Deleted)
                        {
                            ani.RecycleItem.Remove();
                        }
                    }
                }
                LinkedPad = sender;
                if (LinkedPad != null)
                {
                    if (LinkedPad.ObjectState == ObjectState.Deleted)
                    {
                        lvWastedObjects.Items.Add(LinkedPad.RecycleItem);
                    }
                    foreach (CalculatedParameter item in LinkedPad.Parameters)
                    {
                        if (item.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(item.RecycleItem);
                        }
                    }
                    foreach (LayerItem item in LinkedPad.Layer.Items)
                    {
                        if (item.LinkedObj == null) continue;
                        if (item.LinkedObj.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(item.LinkedObj.RecycleItem);
                        }
                    }
                    foreach (AnimationBase ani in LinkedPad.Animations)
                    {
                        if (ani.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(ani.RecycleItem);
                        }
                    }
                }
            }
        }
        public RecycleBinWindow()
        {
            InitializeComponent();
            ChangeColorTheme(Settings.Instance.ColorTheme);
        }
        public void ChangeColorTheme(UIColorTheme theme)
        {
            switch (theme)
            {
                case UIColorTheme.Light:
                    EnableVSRenderer(VisualStudioToolStripExtender.VsVersion.Vs2015, vS2015LightTheme1);
                    break;
                case UIColorTheme.Blue:
                    EnableVSRenderer(VisualStudioToolStripExtender.VsVersion.Vs2015, vS2015BlueTheme1);
                    break;
                case UIColorTheme.Dark:
                    EnableVSRenderer(VisualStudioToolStripExtender.VsVersion.Vs2015, vS2015DarkTheme1);
                    break;
            }
        }
        void EnableVSRenderer(VisualStudioToolStripExtender.VsVersion version, ThemeBase theme)
        {
            visualStudioToolStripExtender1.SetStyle(toolStrip1, version, theme);
        }
        private void tsbRecover_Click(object sender, EventArgs e)
        {
            Recover();
        }
        public void Recover(bool all = false)
        {
            List<IRecoverableDelete> tmp = new List<IRecoverableDelete>();
            foreach (ListViewItem item in lvWastedObjects.GetItems(all))
            {
                IRecoverableDelete ird = item.Tag as IRecoverableDelete;
                if (item.Tag is BasicParameter)//参数直接恢复，不支持撤销
                {
                    try
                    {
                        ird.Recover();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, Resources.Translate("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    if (item.Tag is SketchPad)//画板直接恢复，不支持撤销
                    {
                        try
                        {
                            ird.Recover();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, Resources.Translate("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        if (item.Tag is Base || item.Tag is AnimationBase)
                        {
                            tmp.Add(ird);
                        }
                    }
                }
            }
            if (tmp.Count > 0)
            {
                RecoverObjects<IRecoverableDelete> rec = new RecoverObjects<IRecoverableDelete>(tmp);
                rec.DeleteObject += LayerControl.DeleteObjectHandler;
                rec.RecoverObject += LayerControl.RecoverObjectHandler;
                try
                {
                    rec.Redo();
                }
                catch (Exception ex)
                {
                    HashSet<IRecoverableDelete> done = ex.Data["RecoveredObjects"] as HashSet<IRecoverableDelete>;
                    if (done != null)
                    {
                        rec.RemoveObjects((IRecoverableDelete ird) => { return !done.Contains(ird); });
                        if (ex.Message != Flags.ExceptionShieldMessage)
                        {
                            MessageBox.Show(ex.Message, Resources.Translate("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                }
                finally
                {
                    if (rec.ObjectCount > 0)
                    {
                        LinkedPad.AddNewCommand(rec, false);
                    }
                }
            }
            LinkedDocument.Modified = true;
        }
        private void tsbRecoverAll_Click(object sender, EventArgs e)
        {
            if (lvWastedObjects.Items.Count == 0) return;
            Recover(true);
        }

        private void lvWastedObjects_SelectedIndexChanged(object sender, EventArgs e)
        {
            tsbRecover.Enabled = tsbDelete.Enabled = lvWastedObjects.SelectedItems.Count > 0;
        }

        private void tsbTopMost_CheckedChanged(object sender, EventArgs e)
        {
            TopMost = tsbTopMost.Checked;
        }
        private void RecycleBinWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                Hide();
                e.Cancel = true;
            }
            Program.WinMain.RecycleBinMenu.Checked = false;
        }
        public void Delete(bool all = false)
        {
            foreach (ListViewItem item in lvWastedObjects.GetItems(all))
            {
                IRecoverableDelete ird = item.Tag as IRecoverableDelete;
                ird.Delete();
            }
            LinkedDocument.Modified = true;
        }
        private void tsbDelete_Click(object sender, EventArgs e)
        {
            Delete();
        }

        private void tsbShowOtherWaste_CheckedChanged(object sender, EventArgs e)
        {
            if (Settings.Instance.ShowOtherPadRecycleItems = tsbShowOtherWaste.Checked)
            {
                foreach (SketchPad pad in LinkedDocument.Pads)
                {
                    if (ReferenceEquals(pad, LinkedPad)) continue;
                    if (pad.ObjectState == ObjectState.Deleted)
                    {
                        lvWastedObjects.Items.Add(pad.RecycleItem);
                    }
                    foreach (CalculatedParameter item in pad.Parameters)
                    {
                        if (item.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(item.RecycleItem);
                        }
                    }
                    foreach (LayerItem item in pad.Layer.Items)
                    {
                        if (item.LinkedObj == null) continue;
                        if (item.LinkedObj.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(item.LinkedObj.RecycleItem);
                        }
                    }
                    foreach (AnimationBase ani in pad.Animations)
                    {
                        if (ani.ObjectState == ObjectState.Deleted)
                        {
                            lvWastedObjects.Items.Add(ani.RecycleItem);
                        }
                    }
                }
            }
            else
            {
                foreach (SketchPad pad in LinkedDocument.Pads)
                {
                    if (ReferenceEquals(pad, LinkedPad)) continue;
                    if (pad.ObjectState == ObjectState.Deleted)
                    {
                        pad.RecycleItem.Remove();
                    }
                    foreach (CalculatedParameter item in pad.Parameters)
                    {
                        if (item.ObjectState == ObjectState.Deleted)
                        {
                            item.RecycleItem.Remove();
                        }
                    }
                    foreach (LayerItem item in pad.Layer.Items)
                    {
                        if (item.LinkedObj == null) continue;
                        if (item.LinkedObj.ObjectState == ObjectState.Deleted)
                        {
                            item.LinkedObj.RecycleItem.Remove();
                        }
                    }
                    foreach (AnimationBase ani in pad.Animations)
                    {
                        if (ani.ObjectState == ObjectState.Deleted)
                        {
                            ani.RecycleItem.Remove();
                        }
                    }
                }
            }
        }

        public void Delete(IRecoverableDelete obj)
        {
            lvWastedObjects.Items.Add(obj.RecycleItem);
        }
    }
}
